package com.xg.sys.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xg.frame.log.annotation.LogAnnotation;
import com.xg.sys.entity.SysRole;
import com.xg.sys.entity.SysRoleMenu;
import com.xg.sys.entity.SysUserRole;
import com.xg.sys.service.SysRoleMenuService;
import com.xg.sys.service.SysRoleService;
import com.xg.sys.service.SysUserRoleService;
import com.xg.sys.vo.PageVO;
import com.xg.sys.vo.RoleVO;
import com.xg.utils.DDDUtils;
import com.xg.frame.constant.SysConstant;
import com.xg.frame.constant.UrlConstant;
import com.xg.frame.entity.R;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author tzt
 * @date Created in 2021/8/12 16:40
 * @description：角色管理
 * @modified By：
 */
@Controller
@RequestMapping(UrlConstant.WEB_ADMIN_URL + "/role")
public class RoleController {
    @Resource
    private SysRoleService sysRoleService;
    @Resource
    private SysRoleMenuService sysRoleMenuService;
    @Resource
    private SysUserRoleService sysUserRoleService;

    @GetMapping
    public String index(Model model) throws Exception {
        return "/sys/role/list";
    }

    @GetMapping(value = "/query")
    @ResponseBody
    public PageVO<RoleVO> query(String roleName, String status, Page<SysRole> page, String userId) throws Exception {
        PageVO<RoleVO> returnVO = new PageVO<>();
        if (userId != null) {
            List<Long> roleIdList = sysUserRoleService.list(
                    new LambdaQueryWrapper<SysUserRole>()
                            .select(SysUserRole::getRoleId)
                            .eq(SysUserRole::getUserId, userId)
            ).stream()
                    .map(SysUserRole::getRoleId)
                    .collect(Collectors.toList());
            returnVO.setSelectedIds(roleIdList);
        }
        page = sysRoleService.page(
                page,
                new LambdaQueryWrapper<SysRole>()
                        .like(StringUtils.isNotEmpty(roleName), SysRole::getRoleName, roleName)
                        .eq(StringUtils.isNotEmpty(status), SysRole::getStatus, status)
        );
        return returnVO
                .setTotal(page.getTotal())
                .setRows(DDDUtils.collection(page.getRecords(), RoleVO.class));
    }

    @GetMapping(value = "/edit")
    public String edit(Model model, Long id) {
        RoleVO role = new RoleVO();
        if (Objects.isNull(id)) {
            role.setStatus(SysConstant.STATUS_Y);
            model.addAttribute("title", SysConstant.ADD);
        } else {
            SysRole byId = sysRoleService.getById(id);
            BeanUtils.copyProperties(byId, role);
            model.addAttribute("title", SysConstant.EDIT);
        }
        model.addAttribute("role", role);
        return "/sys/role/edit";
    }

    @LogAnnotation(module = UrlConstant.sysCenter, describe = "角色新增修改")
    @RequiresPermissions("roel:save")
    @PostMapping("/save")
    @ResponseBody
    public R save(RoleVO roleVO, Model model) {
        //校验角色名
        List<SysRole> roleList = sysRoleService.getByRoleName(roleVO.getRoleName());
        if (Objects.isNull(roleVO.getId())) {
            //新增校验
            if (!roleList.isEmpty()) {
                return R.error().message("已存在相同角色名称！");
            }

        }else {
            //修改校验
            if (roleList.size() >1 || (roleList.size()==1&&(!roleList.get(0).getId().equals(roleVO.getId())))) {
                return R.error().message("已存在相同角色名称！");
            }
        }

        //校验成功
        SysRole role = new SysRole();
        BeanUtils.copyProperties(roleVO, role);
        boolean result = false;
        if (Objects.isNull(roleVO.getId())) {
            result = sysRoleService.save(role);
            return result ? R.ok().message("保存成功！") : R.error().message("保存失败！");
        } else {
            result = sysRoleService.updateById(role);
            return result ? R.ok().message("修改成功！") : R.error().message("修改失败！");
        }
    }

    @GetMapping("/validDel")
    @ResponseBody
    public R validDel(@NotBlank String id) {
        String[] ids = id.split(",");
        List<Long> idList = Arrays.stream(ids).map(item -> Long.parseLong(item)).collect(Collectors.toList());
        List<SysUserRole> userRoleList = sysUserRoleService.getUserRoleByRidList(idList);
        List<SysRoleMenu> roleMenuList = sysRoleMenuService.getRoleMenuByRidList(idList);
        if (CollectionUtils.isNotEmpty(userRoleList) || CollectionUtils.isNotEmpty(roleMenuList)) {
            return R.error().message("该角色已经分配用户/菜单，是否确认删除该角色?");
        }
        return R.ok();
    }

    @LogAnnotation(module = UrlConstant.sysCenter, describe = "角色删除")
    @RequiresPermissions("roel:del")
    @GetMapping("/del")
    @ResponseBody
    public R del(@NotBlank String id) {
        String[] ids = id.split(",");
        List<Long> idList = Arrays.stream(ids).map(item -> Long.parseLong(item)).collect(Collectors.toList());
        boolean b = sysRoleService.removeRole(idList);
        return b ? R.ok() : R.error();
    }

    @LogAnnotation(module = UrlConstant.sysCenter, describe = "角色绑定菜单")
    @RequiresPermissions("roel:menu")
    @PostMapping("/relateMenu")
    @ResponseBody
    public R relateMenu(@RequestParam List<Long> res, @RequestParam Long roleId) {
        boolean result = sysRoleMenuService.saveRoleOrUpdateRole(roleId, res);
        return result ? R.ok() : R.error();
    }
}
